package csu.web.credit_bank.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import csu.web.credit_bank.mapper.CourseResourcesMapper;
import csu.web.credit_bank.mapper.LearningProgressMapper;
import csu.web.credit_bank.mapper.StudentViewedResourceMapper;
import csu.web.credit_bank.pojo.CourseResource;
import csu.web.credit_bank.pojo.LearningProgress;
import csu.web.credit_bank.pojo.StudentViewedResource;
import csu.web.credit_bank.service.LearningProgressService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import csu.web.credit_bank.utils.UUIDManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

@Service
public class LearningProgressServiceImpl extends ServiceImpl<LearningProgressMapper, LearningProgress> implements LearningProgressService {

    private static final Logger log = LoggerFactory.getLogger(LearningProgressServiceImpl.class);

    @Autowired
    private StudentViewedResourceMapper viewedResourceMapper;

    @Autowired
    private CourseResourcesMapper courseResourcesMapper;

    @Autowired
    private LearningProgressMapper learningProgressMapper;

    @Autowired
    private UUIDManager uuidManager;

    @Override
    @Transactional
    public LearningProgress createOrUpdateProgress(LearningProgress progress) {
        // 【修复】: 使用通用的 update 方法替代 updateById 来处理复合主键
        QueryWrapper<LearningProgress> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", progress.getStudentId());
        wrapper.eq("course_id", progress.getCourseId());

        // 只更新进度和时间字段
        LearningProgress updatePayload = new LearningProgress();
        updatePayload.setProgressPercent(progress.getProgressPercent());
        updatePayload.setUpdateTime(new Date());

        int updatedRows = learningProgressMapper.update(updatePayload, wrapper);

        if (updatedRows == 0) {
            // 如果没有行被更新，说明记录不存在，则插入新记录
            progress.setUpdateTime(new Date());
            learningProgressMapper.insert(progress);
        }
        return getProgress(progress.getStudentId(), progress.getCourseId());
    }

    @Override
    public LearningProgress getProgress(String studentId, String courseId) {
        return this.getOne(new QueryWrapper<LearningProgress>()
                .eq("student_id", studentId)
                .eq("course_id", courseId));
    }

    @Override
    public List<LearningProgress> getProgressByStudent(String studentId) {
        return this.list(new QueryWrapper<LearningProgress>().eq("student_id", studentId));
    }

    @Override
    public boolean deleteProgress(String studentId, String courseId) {
        return this.remove(new QueryWrapper<LearningProgress>()
                .eq("student_id", studentId)
                .eq("course_id", courseId));
    }

    @Override
    @Transactional
    public void updateProgressAfterResourceView(String studentId, String courseId, String resourceId) {
        try {
            String id = uuidManager.getUUID();
            if (id == null) {
                throw new RuntimeException("无法获取UUID，记录学习进度失败");
            }
            StudentViewedResource newView = new StudentViewedResource(id, studentId, courseId, resourceId, new Date());
            viewedResourceMapper.insert(newView);
        } catch (DuplicateKeyException e) {
            log.info("学生 {} 对资源 {} 的查看记录已存在，无需重复处理。", studentId, resourceId);
            return;
        }

        QueryWrapper<LearningProgress> lockWrapper = new QueryWrapper<>();
        lockWrapper.eq("student_id", studentId).eq("course_id", courseId).last("FOR UPDATE");
        LearningProgress progress = learningProgressMapper.selectOne(lockWrapper);

        QueryWrapper<CourseResource> totalWrapper = new QueryWrapper<>();
        totalWrapper.eq("course_id", courseId);
        long totalResources = courseResourcesMapper.selectCount(totalWrapper);

        if (totalResources == 0) {
            return;
        }

        QueryWrapper<StudentViewedResource> learnedWrapper = new QueryWrapper<>();
        learnedWrapper.eq("student_id", studentId).eq("course_id", courseId);
        long learnedResources = viewedResourceMapper.selectCount(learnedWrapper);

        BigDecimal progressPercent = BigDecimal.valueOf(learnedResources)
                .divide(BigDecimal.valueOf(totalResources), 4, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));

        if (progress != null) {
            // 【修复】: 使用通用的 update 方法替代 updateById
            LearningProgress updatePayload = new LearningProgress();
            updatePayload.setProgressPercent(progressPercent);

            QueryWrapper<LearningProgress> updateWrapper = new QueryWrapper<>();
            updateWrapper.eq("student_id", studentId);
            updateWrapper.eq("course_id", courseId);

            learningProgressMapper.update(updatePayload, updateWrapper);
        } else {
            LearningProgress newProgress = new LearningProgress();
            newProgress.setStudentId(studentId);
            newProgress.setCourseId(courseId);
            newProgress.setProgressPercent(progressPercent);
            newProgress.setUpdateTime(new Date());
            learningProgressMapper.insert(newProgress);
        }
    }
}